<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Pipeline_to_Pulse.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Wraps a module with a pulse input interface inside a ready/valid input handshake interface. Supports full throughput (one input per cycle) if necessary, though that's not usually the case when this interface is needed.">
<title>Pipeline to Pulse</title>
</head>
<body>

<p class="inline bordered"><b><a href="./Pipeline_to_Pulse.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>

<h1>Pipeline to Pulse Interface</h1>
<p>Wraps a module with a pulse input interface inside a ready/valid input
 handshake interface. Supports full throughput (one input per cycle) if
 necessary, though that's not usually the case when this interface is
 needed.</p>
<p><em>The connected module must have at least one pipeline stage from input to
 output. No combinational paths allowed else the input and output handshake
 logic will form a loop.</em></p>
<p>When we have a module that cannot be fully pipelined due to a data
 dependency (e.g.: because of a backwards loop in the pipeline, or simply by
 the iterative nature of the implemented algorithm), and thus cannot accept
 a new input every cycle (i.e.: it has an initiation interval greater than
 1), then we design the connected module to accept a new input with
 a one-cycle valid pulse</p>
<p>This Pipeline to Pulse module converts a pipeline input with a ready/valid
 handshake into a pulse input interface and prevents updating the input
 faster than the connected module can handle, based on a separate signal
 which indicates that new data can be accepted, usually from a similar
 output handshake interface.</p>
<p>We assume here that the connected module is not C-Slowed, though that is
 allowed. You will have to keep track of the separate computation streams
 yourself in the enclosing module.</p>

<pre>
`default_nettype none

module <a href="./Pipeline_to_Pulse.html">Pipeline_to_Pulse</a>
#(
    parameter WORD_WIDTH = 0
)
(
    input   wire                        clock,
    input   wire                        clear,

    // Pipeline input
    input   wire                        valid_in,
    output  reg                         ready_in,
    input   wire    [WORD_WIDTH-1:0]    data_in,

    // Pulse interface to connected module input
    output  reg     [WORD_WIDTH-1:0]    module_data_in,
    output  reg                         module_data_in_valid,

    // Signal that the module can accept the next input
    input   wire                        module_ready
);

    localparam WORD_ZERO = {WORD_WIDTH{1'b0}};

    initial begin
        ready_in                = 1'b1; // matches logic below for simulation
        module_data_in          = WORD_ZERO;
        module_data_in_valid    = 1'b0;
    end
</pre>

<p>Express the usual conditions to complete a ready/valid handshake. </p>

<pre>
    reg input_handshake_done = 1'b0;

    always @(*) begin
        input_handshake_done = (valid_in == 1'b1) && (ready_in == 1'b1);
    end
</pre>

<p>Input data goes straight into the connected module once the input handshake
 is complete. The <code>input_handshake_done</code> signal will be interrupted and
 become a single-cycle pulse by later logic.</p>

<pre>
    always @(*) begin
        module_data_in          = data_in;
        module_data_in_valid    = (input_handshake_done == 1'b1); 
    end
</pre>

<p>We need to have <code>ready_in</code> be 1 both initially and after a <code>clear</code>, else we
 can't complete the initial input handshake (as the connected module has no
 input readiness signal, by design) and nothing would ever start.  This
 initial state contradicts the use of "clear" to bring <code>ready_in_latched</code>
 back to zero once the input handshake is done. So we instead keep that
 initial state in a separate pulse latch. It starts cleared and will get set
 exactly <em>once</em> when the initial input handshake completes, and stay
 constant until cleared.</p>

<pre>
    wire initial_ready_in;

    <a href="./Pulse_Latch.html">Pulse_Latch</a>
    #(
        .RESET_VALUE    (1'b0)
    )
    generate_initial_ready_in
    (
        .clock          (clock),
        .clear          (clear),
        .pulse_in       (input_handshake_done),
        .level_out      (initial_ready_in)
    );
</pre>

<p>Now latch the value of <code>ready_in</code> which is set by signalling the connected
 module is ready, and cleared when completing the input handshake (or by
 <code>clear</code>).</p>

<pre>
    reg clear_ready_in_latched = 1'b0;

    always @(*) begin
        clear_ready_in_latched = (input_handshake_done == 1'b1) || (clear == 1'b1);
    end

    wire ready_in_latched;

    <a href="./Pulse_Latch.html">Pulse_Latch</a>
    #(
        .RESET_VALUE    (1'b0)
    )
    generate_ready_in_latched
    (
        .clock      (clock),
        .clear      (clear_ready_in_latched),
        .pulse_in   (module_ready),
        .level_out  (ready_in_latched)
    );
</pre>

<p>Use the initial state, pass <code>module_ready</code> to <code>ready_in</code> to remove a cycle
 of latency, and latch the ready state if we don't finish an input handshake
 right away.</p>

<pre>
    always @(*) begin
        ready_in = (initial_ready_in == 1'b0) || (ready_in_latched == 1'b1) || (module_ready == 1'b1);
    end

endmodule
</pre>

<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>

